(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    (global = global || self, global['hops-agent-wa'] = factory());
}(this, (function () { 'use strict';

    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation.

    Permission to use, copy, modify, and/or distribute this software for any
    purpose with or without fee is hereby granted.

    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
    PERFORMANCE OF THIS SOFTWARE.
    ***************************************************************************** */

    var __assign = function() {
        __assign = Object.assign || function __assign(t) {
            for (var s, i = 1, n = arguments.length; i < n; i++) {
                s = arguments[i];
                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
            }
            return t;
        };
        return __assign.apply(this, arguments);
    };

    function __awaiter(thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    }

    function __generator(thisArg, body) {
        var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
        return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
        function verb(n) { return function (v) { return step([n, v]); }; }
        function step(op) {
            if (f) throw new TypeError("Generator is already executing.");
            while (_) try {
                if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
                if (y = 0, t) op = [op[0] & 2, t.value];
                switch (op[0]) {
                    case 0: case 1: t = op; break;
                    case 4: _.label++; return { value: op[1], done: false };
                    case 5: _.label++; y = op[1]; op = [0]; continue;
                    case 7: op = _.ops.pop(); _.trys.pop(); continue;
                    default:
                        if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                        if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                        if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                        if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                        if (t[2]) _.ops.pop();
                        _.trys.pop(); continue;
                }
                op = body.call(thisArg, _);
            } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
            if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
        }
    }

    function __spreadArrays() {
        for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
        for (var r = Array(s), k = 0, i = 0; i < il; i++)
            for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
                r[k] = a[j];
        return r;
    }

    var _a;
    var UploadType;
    (function (UploadType) {
        UploadType["API"] = "api";
        UploadType["SEGMENT"] = "segment";
        UploadType["BEHAVIOR"] = "behavior";
    })(UploadType || (UploadType = {}));
    // 默认参数
    var Config = {
        // 监控上报地址
        reportUrl: location.origin,
        // skyWorking上报地址
        collector: location.origin,
        // 自定义上报地址
        customUrl: location.origin,
        // 服务id
        serviceId: '',
        //服务名：
        service: '',
        // app版本
        serviceVersion: '1.0.0',
        // 环境
        environment: 'production',
        // 脚本延迟上报时间
        outtime: 30 * 1000,
        useFmp: true,
        enableSPA: true,
        autoSendPv: true,
        autoTracePerf: true,
        isAjax: true,
        resourceDelay: 0,
        isResource: false,
        isError: false,
        isBehavior: false,
        isCustom: true,
        ignore: {
            ignoreErrors: [],
            ignoreUrls: [],
            ignoreApis: ['/api/v1/report/web'],
        },
        behavior: {
            console: ['log', 'error'],
            click: true,
        },
        // 最长上报数据长度
        maxLength: 1000,
        hashRouter: 'history',
        pagePath: '',
        detailMode: true,
        handlers: (_a = {},
            _a[UploadType.SEGMENT] = [],
            _a[UploadType.API] = [],
            _a[UploadType.BEHAVIOR] = [],
            _a),
        recordHandler: null,
    };
    // 设置参数
    function setConfig(options) {
        Config = __assign(__assign({}, Config), options);
    }
    function getConfig(e) {
        return e ? (Config[e] ? Config[e] : false) : false;
    }
    /**
     * 获取需要过滤的api
     * 默认过滤 reportUrl collector
     */
    function getIgnoreApis() {
        return __spreadArrays(getConfig('ignore').ignoreApis, [Config.reportUrl, Config.collector]);
    }
    /**
     * 获取处理后的上报数据
     */
    function getHandledData(url, data) {
        if ('function' !== typeof getConfig('recordHandler')) {
            return data;
        }
        return getConfig('recordHandler')(url, data);
    }
    /**
     * 顺序执行处理程序
     */
    function execHandler(type, data) {
        var _a;
        var extraArgs = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            extraArgs[_i - 2] = arguments[_i];
        }
        if (!Config.handlers[type].length)
            return data;
        return (_a = Config.handlers[type].reduce(function (s, fn) { return fn.call.apply(fn, __spreadArrays([null, s], extraArgs)); }, data)) !== null && _a !== void 0 ? _a : null;
    }

    // 默认参数
    var GlobalVal = {
        page: '',
        sid: '',
        contextId: '',
        sBegin: Date.now(),
        _health: {
            errcount: 0,
            apisucc: 0,
            apifail: 0,
        },
        circle: false,
        cssInserted: false,
        segments: [],
        monitorSegments: [],
        /**
         * 自定义数据报文
         */
        customMsg: [],
    };
    function setGlobalPage(page) {
        GlobalVal.page = page;
    }
    function setGlobalContextId(uuid) {
        GlobalVal.contextId = uuid;
    }
    function resetGlobalMonitorSegments() {
        GlobalVal.monitorSegments = [];
    }
    function addGlobalMonitorSegments(segment) {
        GlobalVal.monitorSegments.push(segment);
    }
    function resetGlobalSkySegments() {
        GlobalVal.segments = [];
    }
    function addGlobalSkySegments(segment) {
        GlobalVal.segments.push(segment);
    }
    function resetGlobalCustomMsg() {
        GlobalVal.customMsg = [];
    }
    function addGlobalCustomMsg(msg) {
        GlobalVal.customMsg.push(msg);
    }

    var noop = function () { };
    function randomString() {
        for (var e, t, n = 20, r = new Array(n), a = Date.now().toString(36).split(''); n-- > 0;)
            (t = (e = (36 * Math.random()) | 0).toString(36)), (r[n] = e % 3 ? t : t.toUpperCase());
        for (var i = 0; i < 8; i++)
            r.splice(3 * i + 2, 0, a[i]);
        return r.join('');
    }
    function each(data, fn) {
        var n = 0, r = data.length;
        if (isTypeOf(data, 'Array'))
            for (; n < r && !1 !== fn.call(data[n], data[n], n); n++)
                ;
        else
            for (var m in data)
                if (!1 === fn.call(data[m], data[m], m))
                    break;
        return data;
    }
    /**
     * 是否是某类型
     *
     * @export
     * @param {*} data
     * @param {*} type
     * @returns 有type就返回true/false,没有就返回对于类型
     */
    function isTypeOf(data, type) {
        var n = Object.prototype.toString.call(data).substring(8).replace(']', '');
        return type ? n === type : n;
    }
    var on = function (event, fn, remove) {
        window.addEventListener
            ? window.addEventListener(event, function a(e) {
                // remove && window.removeEventListener(event, a, true);
                fn.call(this, e);
            }, true)
            : window.attachEvent &&
                window.attachEvent('on' + event, function i(a) {
                    // remove && window.detachEvent("on" + event, i);
                    fn.call(this, a);
                });
    };
    var parseHash = function (e) {
        return (e ? parseUrl(e.replace(/^#\/?/, '')) : '') || '[index]';
    };
    var parseUrl = function (e) {
        return e && 'string' == typeof e ? e.replace(/^(https?:)?\/\//, '').replace(/\?.*$/, '') : '';
    };
    // 函数toString方法
    var fnToString = function (e) {
        return function () {
            return e + '() { [native code] }';
        };
    };
    var warn = (function () {
        var e = 'object' == typeof console ? console.warn : noop;
        try {
            var t = {
                warn: e,
            };
            t.warn.call(t);
        }
        catch (n) {
            return noop;
        }
        return e;
    })();
    // 自定义事件，并dispatch
    var dispatchCustomEvent = function (e, t) {
        var r;
        window.CustomEvent
            ? (r = new CustomEvent(e, {
                detail: t,
            }))
            : ((r = window.document.createEvent('HTMLEvents')).initEvent(e, !1, !0), (r.detail = t));
        window.dispatchEvent(r);
    };
    // HACK: 在IE浏览器及猎豹浏览器中，对象不支持findIndex的问题
    var findIndex = function (arr, fn) {
        if (Array.isArray(arr)) {
            return arr.reduce(function (carry, item, idx) {
                if (fn(item, idx)) {
                    return idx;
                }
                return carry;
            }, -1);
        }
        return -1;
    };
    // 检查是否是Edge浏览器
    var checkEdge = function () {
        var isEdge = navigator.userAgent.indexOf('Edge') > -1;
        return isEdge;
    };
    var isInIframe = self != top;
    // 获取页面
    function getPage() {
        if (GlobalVal.page)
            return GlobalVal.page;
        else {
            return location.pathname.toLowerCase();
        }
    }
    // 获取uid
    function getUid() {
        var uid = localStorage.getItem('bombay_uid') || '';
        if (!uid) {
            uid = randomString();
            localStorage.setItem('bombay_uid', uid);
        }
        return uid;
    }

    function getCommonMsg() {
        var returnCitySN = window.returnCitySN;
        var u = navigator.connection;
        var data = {
            uploadType: '',
            t: '',
            page: getPage(),
            times: 1,
            serviceVersion: Config.serviceVersion,
            serviceId: Config.serviceId,
            e: Config.environment,
            begin: new Date().getTime(),
            customerKey: getUid(),
            sid: GlobalVal.sid,
            sr: screen.width + 'x' + screen.height,
            vp: getScreen(),
            ct: u ? u.effectiveType : '',
            ul: getLang(),
            _v: '0.7.1',
            o: location.href,
            ip: returnCitySN.cip,
            contry: '',
            province: returnCitySN.cname,
            city: '',
            userAgent: window.navigator.userAgent,
        };
        return data;
    }
    // 获得sid
    // TODO: 单页面
    // function getSid() {
    //   const date = new Date();
    //   let sid = sessionStorage.getItem('bombay_sid') || '';
    //   if (!sid) {
    //       sid = randomString();
    //       sessionStorage.setItem('bombay_sid', sid);
    //   }
    //   return sid;
    // }
    // 获取浏览器默认语言
    function getLang() {
        var lang = navigator.language || navigator.userLanguage; //常规浏览器语言和IE浏览器
        lang = lang.substr(0, 2); //截取lang前2位字符
        return lang;
    }
    function getScreen() {
        var w = document.documentElement.clientWidth || document.body.clientWidth;
        var h = document.documentElement.clientHeight || document.body.clientHeight;
        return w + 'x' + h;
    }

    var Report = /** @class */ (function () {
        function Report() {
            this.url = Config.reportUrl;
        }
        Report.prototype.sendByFetch = function (data) {
            delete data.collector;
            if (!this.url) {
                return;
            }
            var sendRequest = new Request("" + Config.reportUrl, {
                method: 'POST',
                body: JSON.stringify(data),
            });
            fetch(sendRequest)
                .then(function (response) {
                if (response.status >= 400 || response.status === 0) {
                    throw new Error('Something went wrong on api server!');
                }
            })
                .catch(function (error) {
                console.error(error);
            });
        };
        Report.prototype.sendByXhr = function (data, callback) {
            this.url = Config.reportUrl;
            var XMLHttpRequest = window.__oXMLHttpRequest_ || window.XMLHttpRequest;
            delete data.collector;
            if (!this.url) {
                return;
            }
            var xhr = new XMLHttpRequest();
            xhr.open('post', this.url, true);
            xhr.setRequestHeader('Content-Type', 'application/json');
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4 && xhr.status < 400) {
                    // console.log('Report successfully');
                    callback === null || callback === void 0 ? void 0 : callback();
                }
            };
            var sendData = Array.isArray(data) ? data : [data];
            xhr.send(JSON.stringify(getHandledData(this.url, sendData)));
        };
        Report.prototype.sendByXhrToSky = function (data) {
            this.url = 'http://127.0.0.1:8080//v3/segments';
            var XMLHttpRequest = window.__oXMLHttpRequest_ || window.XMLHttpRequest;
            delete data.collector;
            if (!this.url) {
                return;
            }
            var xhr = new XMLHttpRequest();
            xhr.open('post', this.url, true);
            xhr.setRequestHeader('Content-Type', 'application/json');
            xhr.onreadystatechange = function () {
            };
            xhr.send(JSON.stringify(data));
        };
        Report.prototype.handleFetchApi = function (url, success, time, code, res, beigin, req) {
            return __awaiter(this, void 0, void 0, function () {
                var msg, _a, _b, _c, _d, commonMsg, apiMsg, include;
                return __generator(this, function (_e) {
                    switch (_e.label) {
                        case 0:
                            if (!url) {
                                warn('[retcode] api is null');
                                return [2 /*return*/];
                            }
                            msg = {};
                            msg.requestBody = JSON.stringify(req.body);
                            req.body && delete req.body;
                            msg.requestHeader = JSON.stringify(req);
                            msg.requestMethod = req.method || 'get';
                            msg.responseHeader = JSON.stringify(res.headers);
                            msg.responseStatus = res.status;
                            _a = req.responseType;
                            switch (_a) {
                                case 'blob': return [3 /*break*/, 1];
                                case 'text': return [3 /*break*/, 3];
                            }
                            return [3 /*break*/, 5];
                        case 1:
                            _b = msg;
                            return [4 /*yield*/, req.blob()];
                        case 2:
                            _b.responseBody = _e.sent();
                            return [3 /*break*/, 7];
                        case 3:
                            _c = msg;
                            return [4 /*yield*/, res.text().substr(0, 1000)];
                        case 4:
                            _c.responseBody = _e.sent();
                            return [3 /*break*/, 7];
                        case 5:
                            _d = msg;
                            return [4 /*yield*/, res.json()];
                        case 6:
                            _d.responseBody = _e.sent();
                            _e.label = 7;
                        case 7:
                            commonMsg = getCommonMsg();
                            apiMsg = __assign(__assign({}, commonMsg), {
                                t: 'api',
                                beigin: beigin,
                                url: url,
                                success: success,
                                time: time,
                                requestHeader: msg.requestHeader,
                                requestBody: msg.requestBody,
                                requestMethod: msg.requestMethod,
                                responseHeader: msg.responseHeader,
                                responseStatus: msg.responseStatus,
                                responseBody: JSON.stringify(msg.responseBody),
                            });
                            include = findIndex(getConfig('ignore').ignoreApis, function (ignoreApi) { return url.indexOf(ignoreApi) > -1; });
                            if (include > -1)
                                return [2 /*return*/];
                            this.sendByXhr(apiMsg);
                            return [2 /*return*/];
                    }
                });
            });
        };
        Report.prototype.handleApi = function (url, success, time, code, res, beigin, req, type) {
            if (!url) {
                warn('[retcode] api is null');
                return;
            }
            var msg = {};
            msg.requestBody = req.body;
            delete req.body;
            msg.requestHeader = req;
            msg.requestMethod = req.method || 'get';
            msg.responseHeader = res.getAllResponseHeaders();
            msg.responseStatus = res.status;
            // msg.responseBody =  res.responseText.length> Config.maxLength ? '{"hint":"Too much data not to show"}':res.responseText;
            msg.responseBody = res.responseText;
            var commonMsg = getCommonMsg();
            var apiMsg = __assign(__assign({}, commonMsg), {
                t: 'api',
                beigin: beigin,
                url: url,
                success: success,
                time: time,
                requestHeader: JSON.stringify(msg.requestHeader),
                requestBody: msg.requestBody,
                requestMethod: msg.requestMethod,
                responseHeader: JSON.stringify(msg.responseHeader),
                responseStatus: msg.responseStatus,
                responseBody: msg.responseBody,
            });
            // 过滤忽略的url
            var include = findIndex(getConfig('ignore').ignoreApis, function (ignoreApi) { return url.indexOf(ignoreApi) > -1; });
            if (include > -1)
                return;
            this.sendByXhr(apiMsg);
        };
        Report.prototype.handleCustomApi = function (url, success, time, code, msg, beigin) {
            if (!url) {
                warn('[retcode] api is null');
                return;
            }
            var commonMsg = getCommonMsg();
            var apiMsg = __assign(__assign({}, commonMsg), {
                t: 'api',
                beigin: beigin,
                url: url,
                success: success,
                time: time,
                requestHeader: msg.requestHeader,
                requestBody: msg.requestBody,
                requestMethod: msg.requestMethod,
                responseHeader: msg.responseHeader,
                responseStatus: msg.responseStatus,
                responseBody: msg.responseBody,
            });
            // 过滤忽略的url
            var include = findIndex(getConfig('ignore').ignoreApis, function (ignoreApi) { return url.indexOf(ignoreApi) > -1; });
            if (include > -1)
                return;
            this.sendByXhr(apiMsg);
        };
        return Report;
    }());
    var report = new Report();

    var BehaviorType;
    (function (BehaviorType) {
        BehaviorType["click"] = "click";
        BehaviorType["navigation"] = "navigation";
        BehaviorType["console_error"] = "console.error";
        BehaviorType["console_log"] = "console.log";
        BehaviorType["console_info"] = "console.info";
    })(BehaviorType || (BehaviorType = {}));
    // 处理pv
    function handlePv() {
        if (!Config.autoSendPv)
            return;
        var commonMsg = getCommonMsg();
        var msg = __assign(__assign({}, commonMsg), {
            t: 'pv',
            uploadType: 'pv',
            dt: document.title,
            dl: location.href,
            dr: document.referrer,
            dpr: window.devicePixelRatio,
            de: document.charset,
        });
        report.sendByXhr(msg);
    }
    // 处理html node
    var normalTarget = function (e) {
        var t, n, r, a, i, o = [];
        if (!e || !e.tagName)
            return '';
        if ((o.push(e.tagName.toLowerCase()), e.id && o.push('#'.concat(e.id)), (t = e.className) && '[object String]' === Object.prototype.toString.call(t))) {
            for (n = t.split(/\s+/), i = 0; i < n.length; i++) {
                // className包含active的不加入路径
                if (n[i].indexOf('active') < 0)
                    o.push('.'.concat(n[i]));
            }
        }
        var s = ['type', 'name', 'title', 'alt'];
        for (i = 0; i < s.length; i++)
            (r = s[i]), (a = e.getAttribute(r)) && o.push('['.concat(r, '="').concat(a, '"]'));
        return o.join('');
    };
    // 获取元素路径，最多保留5层
    var getElmPath = function (e) {
        var _a;
        if (!e || 1 !== e.nodeType)
            return '';
        var ret = [], deepLength = 0, // 层数，最多5层
        elm = ''; // 元素
        ret.push("(" + ((_a = e.innerText) === null || _a === void 0 ? void 0 : _a.substr(0, 50)) + ")");
        for (var t = e || null; t && deepLength++ < 5 && !('html' === (elm = normalTarget(t)));) {
            ret.push(elm), (t = t.parentNode);
        }
        return ret.reverse().join(' > ');
    };
    function handleClick(event) {
        var target;
        try {
            target = event.target;
        }
        catch (u) {
            target = '<unknown>';
        }
        if (target.nodeName === 'INPUT' || target.nodeName === 'TEXTAREA')
            return;
        if (0 !== target.length) {
            var behavior = {
                type: 'ui.click',
                data: {
                    path: getElmPath(target),
                    message: '',
                },
            };
            // 空信息不上报
            if (!behavior.data.path)
                return;
            var commonMsg = getCommonMsg();
            var msg = __assign(__assign({}, commonMsg), {
                t: 'behavior',
                behavior: behavior,
            });
            var handledMsg = execHandler(UploadType.BEHAVIOR, msg, BehaviorType.click, event);
            if (handledMsg && getConfig('isBehavior'))
                report.sendByXhr(handledMsg);
        }
    }
    // 处理hash变化
    // 注意在路由栈的路由不会触发
    function handleHashchange(e) {
        var page = Config.enableSPA ? parseHash(location.hash.toLowerCase()) : location.pathname.toLowerCase();
        page && setPage(page);
    }
    // 处理hash变化
    function handleHistorystatechange(e) {
        var page = Config.enableSPA ? parseHash(e.detail.toLowerCase()) : e.detail.toLowerCase();
        page && setPage(page);
    }
    function handleNavigation(page) {
        var commonMsg = getCommonMsg();
        var msg = __assign(__assign({}, commonMsg), {
            t: 'behavior',
            uploadType: 'behavior',
            behavior: {
                type: 'navigation',
                data: {
                    from: commonMsg.page,
                    to: page,
                },
            },
        });
        var handledMsg = execHandler(UploadType.BEHAVIOR, msg, BehaviorType.navigation);
        if (handledMsg && Config.isBehavior)
            report.sendByXhr(handledMsg);
    }
    function setPage(page) {
        handleNavigation(page);
        if (isInIframe) {
            window.parent.postMessage({
                t: 'setPage',
                href: location.href,
                page: page,
            }, '*');
        }
        setGlobalPage(page);
        handlePv();
    }

    /**
     * hack pushstate replaceState
     * 派送historystatechange historystatechange事件
     * @export
     * @param {('pushState' | 'replaceState')} e
     */
    function hackState(e) {
        var t = history[e];
        'function' == typeof t &&
            ((history[e] = function (n, i, s) {
                !window['__bb_onpopstate_'] && hackOnpopstate(); // 调用pushState或replaceState时hack Onpopstate
                var c = 1 === arguments.length ? [arguments[0]] : Array.apply(null, arguments), u = location.href, f = t.apply(history, c);
                if (!s || 'string' != typeof s)
                    return f;
                if (s === u)
                    return f;
                try {
                    var l = u.split('#'), h = s.split('#'), p = parseUrl(l[0]), d = parseUrl(h[0]), g = l[1] && l[1].replace(/^\/?(.*)/, '$1'), v = h[1] && h[1].replace(/^\/?(.*)/, '$1');
                    p !== d ? dispatchCustomEvent('historystatechanged', d) : g !== v && dispatchCustomEvent('historystatechanged', v);
                }
                catch (m) {
                    warn('[retcode] error in ' + e + ': ' + m);
                }
                return f;
            }),
                (history[e].toString = fnToString(e)));
    }
    function hackOnpopstate() {
        window['__bb_onpopstate_'] = window.onpopstate;
        window.onpopstate = function () {
            for (var r = arguments.length, a = new Array(r), o = 0; o < r; o++)
                a[o] = arguments[o];
            var page = Config.enableSPA && Config.hashRouter === 'hash' ? parseHash(location.hash.toLowerCase()) : location.pathname.toLowerCase();
            setPage(page);
            if (window.__bb_onpopstate_)
                return window.__bb_onpopstate_.apply(this, a);
        };
    }

    /*
     * @Description: 记录 traceid，方便 resource 查询对应请求的 traceid，方便
     */
    var store = new Map();
    var status = 'open';
    /**
     * 生成 trace key
     * @param param0
     */
    var getKey = function (_a) {
        var url = _a.url;
        return url;
    };
    var getTraceId = function (params) {
        if (!store.has(getKey(params)))
            return null;
        return store.get(getKey(params));
    };
    var setTraceId = function (params, traceId) {
        if ('close' === status)
            return;
        store.set(getKey(params), traceId);
    };
    /**
     * 停止记录
     */
    var stopRecording = function () {
        status = 'close';
    };

    var TIMING_KEYS = [
        '',
        'fetchStart',
        'domainLookupStart',
        'domainLookupEnd',
        'connectStart',
        'connectEnd',
        'requestStart',
        'responseStart',
        'responseEnd',
        '',
        'domInteractive',
        '',
        'domContentLoadedEventEnd',
        '',
        'loadEventStart',
        '',
        'msFirstPaint',
        'secureConnectionStart',
    ];
    var Resource = /** @class */ (function () {
        function Resource() {
        }
        Resource.prototype.handleResource = function () {
            var performance = window.performance;
            if (!performance || 'object' != typeof performance || 'function' != typeof performance.getEntriesByType)
                return null;
            var commonMsg = getCommonMsg();
            var msg = __assign(__assign({}, commonMsg), {
                dom: 0,
                load: 0,
                t: 'res',
                uploadType: 'res',
                ress: [],
            });
            var i = performance.timing || {}, o = performance.getEntriesByType('resource') || [];
            if ('function' == typeof window.PerformanceNavigationTiming) {
                var s = performance.getEntriesByType('navigation')[0];
                s && (i = s);
            }
            each({
                dom: [10, 8],
                load: [14, 1],
            }, function (e, t) {
                var r = i[TIMING_KEYS[e[1]]], o = i[TIMING_KEYS[e[0]]];
                if (r !== undefined && o !== undefined) {
                    var s = Math.round(o - r);
                    s >= 0 && s < 36e5 && (msg[t] = s);
                }
            });
            // 过滤忽略的url
            o = o.filter(function (item) {
                var include = findIndex(getIgnoreApis(), function (ignoreApi) { return item.name.indexOf(ignoreApi) > -1; });
                return include > -1 ? false : true;
            });
            // 兼容Edge浏览器无法直接使用PerformanceResourceTiming对象类型的数据进行上报，处理方式是定义变量重新赋值
            if (checkEdge()) {
                var edgeResources = [];
                each(o, function (oItem) {
                    edgeResources.push({
                        connectEnd: oItem.connectEnd,
                        connectStart: oItem.connectStart,
                        domainLookupEnd: oItem.connectStart,
                        domainLookupStart: oItem.domainLookupStart,
                        duration: oItem.duration,
                        entryType: oItem.entryType,
                        fetchStart: oItem.fetchStart,
                        initiatorType: oItem.initiatorType,
                        name: oItem.name,
                        redirectEnd: oItem.redirectEnd,
                        redirectStart: oItem.redirectStart,
                        responseEnd: oItem.responseEnd,
                        responseStart: oItem.responseStart,
                        startTime: oItem.startTime,
                    });
                });
                o = edgeResources;
            }
            // 数据添加 tarceid
            o = o.map(function (item) {
                if ('xmlhttprequest' !== item.initiatorType)
                    return item;
                var traceId = getTraceId({ url: item.name });
                if (!traceId)
                    return item;
                item = item.toJSON(); // 提前json，防止 PerformanceResourceTiming  JSON 后， traceId 字段丢失
                item.traceId = traceId;
                return item;
            });
            msg.ress = o;
            report.sendByXhr(msg, stopRecording);
        };
        return Resource;
    }());
    var resource = new Resource();

    var PagePerf = /** @class */ (function () {
        function PagePerf() {
        }
        PagePerf.prototype.getPerfTiming = function () {
            try {
                if (!window.performance || !window.performance.timing) {
                    console.log('your browser do not support performance');
                    return;
                }
                var timing = window.performance.timing;
                var redirectTime = 0;
                var type = 1;
                var begin = new Date().getTime();
                // 根据PerformanceNavigationTiming计算更准确
                // @ts-ignore
                if ('function' == typeof window.PerformanceNavigationTiming) {
                    var c = performance.getEntriesByType('navigation')[0];
                    if (c) {
                        timing = c;
                        type = 2;
                    }
                }
                if (timing.navigationStart !== undefined) {
                    redirectTime = parseInt(String(timing.fetchStart - timing.navigationStart), 10);
                }
                else if (timing.redirectEnd !== undefined) {
                    redirectTime = parseInt(String(timing.redirectEnd - timing.redirectStart), 10);
                }
                else {
                    redirectTime = 0;
                }
                var u = window.navigator.connection || window.navigator.mozConnection || window.navigator.webkitConnection;
                var f = performance.navigation || { type: undefined };
                var ct = u ? u.effectiveType || u.type : "";
                var l = u ? u.downlink || u.downlinkMax || u.bandwidth || null : null;
                var bandwidth = l > 999 ? 999 : l;
                var navtype = 1 === f.type ? "Reload" : "Other";
                1 === type && timing.fetchStart > 0
                    ? (begin = timing.fetchStart)
                    : 2 === type && parseInt(String(timing.loadEventStart - timing.fetchStart), 10) > 0
                        ? (begin = Date.now() - parseInt(String(timing.loadEventStart - timing.fetchStart), 10))
                        : (begin = Date.now());
                return {
                    redirectTime: redirectTime,
                    dns: parseInt(String(timing.domainLookupEnd - timing.domainLookupStart), 10),
                    ttfb: parseInt(String(timing.responseStart - timing.requestStart), 10),
                    tcp: parseInt(String(timing.connectEnd - timing.connectStart), 10),
                    trans: parseInt(String(timing.responseEnd - timing.responseStart), 10),
                    dom: parseInt(String(timing.domInteractive - timing.responseEnd), 10),
                    fpt: parseInt(String(timing.responseEnd - timing.fetchStart), 10),
                    ready: parseInt(String(timing.domContentLoadedEventEnd - timing.fetchStart), 10),
                    load: parseInt(String(timing.loadEventStart - timing.fetchStart), 10),
                    // Synchronous load resources in the page
                    res: parseInt(String(timing.loadEventStart - timing.domContentLoadedEventEnd), 10),
                    // Only valid for HTTPS
                    ssl: location.protocol === 'https:' && timing.secureConnectionStart > 0 ?
                        parseInt(String(timing.connectEnd - timing.secureConnectionStart), 10) : undefined,
                    tti: parseInt(String(timing.domInteractive - timing.fetchStart), 10),
                    firstbyte: parseInt(String(timing.responseStart - timing.domainLookupStart), 10),
                    fmp: 0,
                    perfTiming: JSON.stringify(timing),
                    bandwidth: bandwidth,
                    ct: ct,
                    navtype: navtype,
                    begin: begin,
                };
            }
            catch (e) {
                throw e;
            }
        };
        return PagePerf;
    }());

    var getStyle = function (element, attr) {
        if (window.getComputedStyle) {
            return window.getComputedStyle(element, null)[attr];
        }
        else {
            return element.currentStyle[attr];
        }
    };
    // element weight for calculate score
    var ELE_WEIGHT;
    (function (ELE_WEIGHT) {
        ELE_WEIGHT[ELE_WEIGHT["SVG"] = 2] = "SVG";
        ELE_WEIGHT[ELE_WEIGHT["IMG"] = 2] = "IMG";
        ELE_WEIGHT[ELE_WEIGHT["CANVAS"] = 4] = "CANVAS";
        ELE_WEIGHT[ELE_WEIGHT["OBJECT"] = 4] = "OBJECT";
        ELE_WEIGHT[ELE_WEIGHT["EMBED"] = 4] = "EMBED";
        ELE_WEIGHT[ELE_WEIGHT["VIDEO"] = 4] = "VIDEO";
    })(ELE_WEIGHT || (ELE_WEIGHT = {}));
    var START_TIME = performance.now();
    var IGNORE_TAG_SET = ['SCRIPT', 'STYLE', 'META', 'HEAD', 'LINK'];
    var LIMIT = 3000;
    var WW = window.innerWidth;
    var WH = window.innerHeight;
    var DELAY = 500; // fmp retry interval
    var FMPTiming = /** @class */ (function () {
        function FMPTiming() {
            this.fmpTime = 0;
            this.statusCollector = []; // nodes change time
            this.flag = true;
            this.observer = null;
            this.callbackCount = 0;
            this.entries = {};
            if (!performance || !performance.getEntries) {
                console.log('your browser do not support performance.getEntries');
                return;
            }
            this.initObserver();
        }
        FMPTiming.prototype.getFirstSnapShot = function () {
            var time = performance.now();
            var $body = document.body;
            if ($body) {
                this.setTag($body, this.callbackCount);
            }
            this.statusCollector.push({
                time: time,
            });
        };
        FMPTiming.prototype.initObserver = function () {
            var _this = this;
            this.getFirstSnapShot();
            this.observer = new MutationObserver(function () {
                _this.callbackCount += 1;
                var time = performance.now();
                var $body = document.body;
                if ($body) {
                    _this.setTag($body, _this.callbackCount);
                }
                _this.statusCollector.push({
                    time: time,
                });
            });
            // observe all child nodes
            this.observer.observe(document, {
                childList: true,
                subtree: true,
            });
            // calculate score when page loaded
            if (document.readyState === 'complete') {
                this.calculateFinalScore();
            }
            else {
                window.addEventListener('load', function () {
                    _this.calculateFinalScore();
                }, false);
            }
        };
        FMPTiming.prototype.calculateFinalScore = function () {
            var _this = this;
            if (MutationEvent && this.flag) {
                if (this.checkNeedCancel(START_TIME)) {
                    // cancel observer for dom change
                    this.observer.disconnect();
                    this.flag = false;
                    var res = this.getTreeScore(document.body);
                    var tp = null;
                    for (var _i = 0, _a = res.dpss; _i < _a.length; _i++) {
                        var item = _a[_i];
                        if (tp && tp.st) {
                            if (tp.st < item.st) {
                                tp = item;
                            }
                        }
                        else {
                            tp = item;
                        }
                    }
                    // Get all of soures load time
                    performance.getEntries().forEach(function (item) {
                        _this.entries[item.name] = item.responseEnd;
                    });
                    if (!tp) {
                        return false;
                    }
                    var resultEls = this.filterResult(tp.els);
                    var fmpTiming = this.getFmpTime(resultEls);
                    this.fmpTime = fmpTiming;
                }
                else {
                    setTimeout(function () {
                        _this.calculateFinalScore();
                    }, DELAY);
                }
            }
        };
        FMPTiming.prototype.getFmpTime = function (resultEls) {
            var _a, _b, _c;
            var rt = 0;
            for (var _i = 0, resultEls_1 = resultEls; _i < resultEls_1.length; _i++) {
                var item = resultEls_1[_i];
                var time = 0;
                if (item.weight === 1) {
                    var index = parseInt(item.ele.getAttribute('fmp_c'), 10);
                    time = (_a = this.statusCollector[index]) === null || _a === void 0 ? void 0 : _a.time;
                }
                else if (item.weight === 2) {
                    if (item.ele.tagName === 'IMG') {
                        time = this.entries[item.ele.src];
                    }
                    else if (item.ele.tagName === 'SVG') {
                        var index = parseInt(item.ele.getAttribute('fmp_c'), 10);
                        time = (_b = this.statusCollector[index]) === null || _b === void 0 ? void 0 : _b.time;
                    }
                    else {
                        var match = getStyle(item.ele, 'background-image').match(/url\(\"(.*?)\"\)/);
                        var url = void 0;
                        if (match && match[1]) {
                            url = match[1];
                        }
                        if (!(url === null || url === void 0 ? void 0 : url.includes('http'))) {
                            if (match) {
                                url = location.protocol + match[1];
                            }
                        }
                        time = this.entries[url];
                    }
                }
                else if (item.weight === 4) {
                    if (item.ele.tagName === 'CANVAS') {
                        var index = parseInt(item.ele.getAttribute('fmp_c'), 10);
                        time = this.statusCollector[index] && ((_c = this.statusCollector[index]) === null || _c === void 0 ? void 0 : _c.time);
                    }
                    else if (item.ele.tagName === 'VIDEO') {
                        time = this.entries[item.ele.src];
                        if (!time) {
                            time = this.entries[item.ele.poster];
                        }
                    }
                }
                if (typeof time !== 'number') {
                    time = 0;
                }
                if (rt < time) {
                    rt = time;
                }
            }
            return rt;
        };
        /**
         * The nodes with the highest score in the visible area are collected and the average value is taken,
         * and the low score ones are eliminated
         */
        FMPTiming.prototype.filterResult = function (els) {
            if (els.length === 1) {
                return els;
            }
            var sum = 0;
            els.forEach(function (item) {
                sum += item.st;
            });
            var avg = sum / els.length;
            return els.filter(function (item) {
                return item.st > avg;
            });
        };
        FMPTiming.prototype.checkNeedCancel = function (start) {
            var time = performance.now() - start;
            var lastCalTime = this.statusCollector.length > 0 ? this.statusCollector[this.statusCollector.length - 1].time : 0;
            return time > LIMIT || time - lastCalTime > 1000;
        };
        FMPTiming.prototype.getTreeScore = function (node) {
            if (!node) {
                return {};
            }
            var dpss = [];
            var children = node.children;
            for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
                var child = children_1[_i];
                // Only calculate marked elements
                if (!child.getAttribute('fmp_c')) {
                    continue;
                }
                var s = this.getTreeScore(child);
                if (s.st) {
                    dpss.push(s);
                }
            }
            return this.calcaulteGrades(node, dpss);
        };
        FMPTiming.prototype.calcaulteGrades = function (ele, dpss) {
            var _a = ele.getBoundingClientRect(), width = _a.width, height = _a.height, left = _a.left, top = _a.top;
            var isInViewPort = true;
            if (WH < top || WW < left) {
                isInViewPort = false;
            }
            var sdp = 0;
            dpss.forEach(function (item) {
                sdp += item.st;
            });
            var weight = Number(ELE_WEIGHT[ele.tagName]) || 1;
            // If there is a common element of the background image, it is calculated according to the picture
            if (weight === 1 &&
                getStyle(ele, 'background-image') &&
                getStyle(ele, 'background-image') !== 'initial' &&
                getStyle(ele, 'background-image') !== 'none') {
                weight = ELE_WEIGHT.IMG;
            }
            // score = the area of element
            var st = isInViewPort ? width * height * weight : 0;
            var els = [{ ele: ele, st: st, weight: weight }];
            var root = ele;
            // The percentage of the current element in the viewport
            var areaPercent = this.calculateAreaParent(ele);
            // If the sum of the child's weights is greater than the parent's true weight
            if (sdp > st * areaPercent || areaPercent === 0) {
                st = sdp;
                els = [];
                for (var _i = 0, dpss_1 = dpss; _i < dpss_1.length; _i++) {
                    var item = dpss_1[_i];
                    els = els.concat(item.els);
                }
            }
            return {
                dpss: dpss,
                st: st,
                els: els,
                root: root,
            };
        };
        FMPTiming.prototype.calculateAreaParent = function (ele) {
            var _a = ele.getBoundingClientRect(), left = _a.left, right = _a.right, top = _a.top, bottom = _a.bottom, width = _a.width, height = _a.height;
            var winLeft = 0;
            var winTop = 0;
            var winRight = WW;
            var winBottom = WH;
            var overlapX = right - left + (winRight - winLeft) - (Math.max(right, winRight) - Math.min(left, winLeft));
            var overlapY = bottom - top + (winBottom - winTop) - (Math.max(bottom, winBottom) - Math.min(top, winTop));
            if (overlapX <= 0 || overlapY <= 0) {
                return 0;
            }
            return (overlapX * overlapY) / (width * height);
        };
        // Depth first traversal to mark nodes
        FMPTiming.prototype.setTag = function (target, callbackCount) {
            var tagName = target.tagName;
            if (IGNORE_TAG_SET.indexOf(tagName) === -1) {
                var $children = target.children;
                if ($children && $children.length > 0) {
                    for (var i = $children.length - 1; i >= 0; i--) {
                        var $child = $children[i];
                        var hasSetTag = $child.getAttribute('fmp_c') !== null;
                        // If it is not marked, whether the marking condition is met is detected
                        if (!hasSetTag) {
                            var _a = $child.getBoundingClientRect(), left = _a.left, top = _a.top, width = _a.width, height = _a.height;
                            if (WH < top || WW < left || width === 0 || height === 0) {
                                continue;
                            }
                            $child.setAttribute('fmp_c', "" + callbackCount);
                        }
                        this.setTag($child, callbackCount);
                    }
                }
            }
        };
        return FMPTiming;
    }());

    var TracePerf = /** @class */ (function () {
        function TracePerf() {
            this.perfConfig = {
                perfDetail: {},
            };
        }
        TracePerf.prototype.recordPerf = function () {
            var _this = this;
            var fmp = { fmpTime: undefined };
            if (Config.autoTracePerf) {
                this.perfConfig.perfDetail = new PagePerf().getPerfTiming();
                if (Config.useFmp) {
                    fmp = new FMPTiming();
                }
            }
            // auto report pv and perf data
            setTimeout(function () {
                var perfDetail = Config.autoTracePerf ? __assign(__assign({}, _this.perfConfig.perfDetail), { fmp: Config.useFmp ? parseInt(String(fmp.fmpTime), 10) : undefined }) : undefined;
                var commonMsg = getCommonMsg();
                var msg = __assign(__assign(__assign({}, commonMsg), { t: 'perf', uploadType: 'perf' }), perfDetail);
                report.sendByXhr(msg);
                // clear perf data
                _this.clearPerf();
            }, 50);
        };
        TracePerf.prototype.clearPerf = function () {
            if (!(window.performance && window.performance.clearResourceTimings)) {
                return;
            }
            window.performance.clearResourceTimings();
            this.perfConfig = {
                perfDetail: {},
            };
        };
        return TracePerf;
    }());
    var tracePerf = new TracePerf();

    var JsError = /** @class */ (function () {
        function JsError() {
        }
        // 处理错误
        JsError.prototype.handleErr = function (error) {
            switch (error.type) {
                case 'error':
                    // 通过instanceof区分,区分捕获的异常还是资源错误
                    // 异常instanceof是ErrorEvent, 资源错误instanceof是Event
                    error instanceof ErrorEvent ? this.reportCaughtError(error) : this.reportResourceError(error);
                    break;
                case 'unhandledrejection':
                    this.reportPromiseError(error);
                    break;
            }
        };
        // 捕获js异常
        JsError.prototype.reportCaughtError = function (error) {
            var _a;
            var commonMsg = getCommonMsg();
            var n = error.name || 'CustomError', a = error.message || '', i = ((_a = error.error) === null || _a === void 0 ? void 0 : _a.stack) || '';
            var msg = __assign(__assign({}, commonMsg), {
                t: 'error',
                uploadType: 'error',
                st: 'caughterror',
                cate: n,
                msg: a && a.substring(0, 200),
                detail: i && i.substring(0, 1e3),
                file: error.filename || '',
                line: error.lineno || '',
                col: error.colno || '',
            });
            report.sendByXhr(msg);
        };
        // 捕获资源异常
        JsError.prototype.reportResourceError = function (error) {
            var _a;
            var commonMsg = getCommonMsg();
            var target = error.target;
            var msg = __assign(__assign({}, commonMsg), {
                t: 'error',
                uploadType: 'error',
                st: 'resource',
                msg: (_a = target.outerHTML) === null || _a === void 0 ? void 0 : _a.substring(0, 200),
                file: target.src,
                stack: target.localName.toUpperCase(),
            });
            report.sendByXhr(msg);
        };
        // 捕获promise异常
        JsError.prototype.reportPromiseError = function (error) {
            var commonMsg = getCommonMsg();
            var msg = __assign(__assign({}, commonMsg), {
                t: 'error',
                uploadType: 'error',
                st: 'promise',
                msg: JSON.stringify(error.reason).substring(0, 200),
            });
            report.sendByXhr(msg);
        };
        return JsError;
    }());
    var jsError = new JsError();

    /**
     *  base64.ts
     *
     *  Licensed under the BSD 3-Clause License.
     *    http://opensource.org/licenses/BSD-3-Clause
     *
     *  References:
     *    http://en.wikipedia.org/wiki/Base64
     *
     * @author Dan Kogai (https://github.com/dankogai)
     */
    const _hasbtoa = typeof btoa === 'function';
    const _hasBuffer = typeof Buffer === 'function';
    const _TD = typeof TextDecoder === 'function' ? new TextDecoder() : undefined;
    const _TE = typeof TextEncoder === 'function' ? new TextEncoder() : undefined;
    const b64ch = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
    const b64chs = [...b64ch];
    const b64tab = ((a) => {
        let tab = {};
        a.forEach((c, i) => tab[c] = i);
        return tab;
    })(b64chs);
    const _fromCC = String.fromCharCode.bind(String);
    const _U8Afrom = typeof Uint8Array.from === 'function'
        ? Uint8Array.from.bind(Uint8Array)
        : (it, fn = (x) => x) => new Uint8Array(Array.prototype.slice.call(it, 0).map(fn));
    const _mkUriSafe = (src) => src
        .replace(/[+\/]/g, (m0) => m0 == '+' ? '-' : '_')
        .replace(/=+$/m, '');
    /**
     * polyfill version of `btoa`
     */
    const btoaPolyfill = (bin) => {
        // console.log('polyfilled');
        let u32, c0, c1, c2, asc = '';
        const pad = bin.length % 3;
        for (let i = 0; i < bin.length;) {
            if ((c0 = bin.charCodeAt(i++)) > 255 ||
                (c1 = bin.charCodeAt(i++)) > 255 ||
                (c2 = bin.charCodeAt(i++)) > 255)
                throw new TypeError('invalid character found');
            u32 = (c0 << 16) | (c1 << 8) | c2;
            asc += b64chs[u32 >> 18 & 63]
                + b64chs[u32 >> 12 & 63]
                + b64chs[u32 >> 6 & 63]
                + b64chs[u32 & 63];
        }
        return pad ? asc.slice(0, pad - 3) + "===".substring(pad) : asc;
    };
    /**
     * does what `window.btoa` of web browsers do.
     * @param {String} bin binary string
     * @returns {string} Base64-encoded string
     */
    const _btoa = _hasbtoa ? (bin) => btoa(bin)
        : _hasBuffer ? (bin) => Buffer.from(bin, 'binary').toString('base64')
            : btoaPolyfill;
    const _fromUint8Array = _hasBuffer
        ? (u8a) => Buffer.from(u8a).toString('base64')
        : (u8a) => {
            // cf. https://stackoverflow.com/questions/12710001/how-to-convert-uint8-array-to-base64-encoded-string/12713326#12713326
            const maxargs = 0x1000;
            let strs = [];
            for (let i = 0, l = u8a.length; i < l; i += maxargs) {
                strs.push(_fromCC.apply(null, u8a.subarray(i, i + maxargs)));
            }
            return _btoa(strs.join(''));
        };
    // This trick is found broken https://github.com/dankogai/js-base64/issues/130
    // const utob = (src: string) => unescape(encodeURIComponent(src));
    // reverting good old fationed regexp
    const cb_utob = (c) => {
        if (c.length < 2) {
            var cc = c.charCodeAt(0);
            return cc < 0x80 ? c
                : cc < 0x800 ? (_fromCC(0xc0 | (cc >>> 6))
                    + _fromCC(0x80 | (cc & 0x3f)))
                    : (_fromCC(0xe0 | ((cc >>> 12) & 0x0f))
                        + _fromCC(0x80 | ((cc >>> 6) & 0x3f))
                        + _fromCC(0x80 | (cc & 0x3f)));
        }
        else {
            var cc = 0x10000
                + (c.charCodeAt(0) - 0xD800) * 0x400
                + (c.charCodeAt(1) - 0xDC00);
            return (_fromCC(0xf0 | ((cc >>> 18) & 0x07))
                + _fromCC(0x80 | ((cc >>> 12) & 0x3f))
                + _fromCC(0x80 | ((cc >>> 6) & 0x3f))
                + _fromCC(0x80 | (cc & 0x3f)));
        }
    };
    const re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
    /**
     * @deprecated should have been internal use only.
     * @param {string} src UTF-8 string
     * @returns {string} UTF-16 string
     */
    const utob = (u) => u.replace(re_utob, cb_utob);
    //
    const _encode = _hasBuffer
        ? (s) => Buffer.from(s, 'utf8').toString('base64')
        : _TE
            ? (s) => _fromUint8Array(_TE.encode(s))
            : (s) => _btoa(utob(s));
    /**
     * converts a UTF-8-encoded string to a Base64 string.
     * @param {boolean} [urlsafe] if `true` make the result URL-safe
     * @returns {string} Base64 string
     */
    const encode = (src, urlsafe = false) => urlsafe
        ? _mkUriSafe(_encode(src))
        : _encode(src);

    /**
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    function xhrInterceptor() {
        var originalXHR = window.XMLHttpRequest;
        window['__oXMLHttpRequest_'] = originalXHR;
        var xhrSend = XMLHttpRequest.prototype.send;
        var xhrOpen = XMLHttpRequest.prototype.open;
        var setRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
        function ajaxEventTrigger(event) {
            var ajaxEvent = new CustomEvent(event, { detail: this });
            window.dispatchEvent(ajaxEvent);
        }
        function customizedXHR() {
            var liveXHR = new originalXHR();
            liveXHR.Config = {
                getOpenParams: [],
                getSendConfig: [],
                getHeader: {}
            };
            liveXHR.addEventListener('readystatechange', function () {
                ajaxEventTrigger.call(this, 'xhrReadyStateChange');
            }, false);
            liveXHR.setRequestHeader = function (key, value) {
                setRequestHeader.apply(this, arguments);
                this.Config.getHeader[key] = value;
            };
            liveXHR.open = function (method, url) {
                this.Config.getOpenParams = arguments;
                this.Config.getHeader['method'] = method;
                return xhrOpen.apply(this, arguments);
            };
            liveXHR.send = function (body) {
                this.Config.getSendParams = arguments;
                return xhrSend.apply(this, arguments);
            };
            return liveXHR;
        }
        window.XMLHttpRequest = customizedXHR;
    }

    /**
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    function uuid() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            /* tslint:disable */
            var r = (Math.random() * 16) | 0;
            /* tslint:disable */
            var v = c === 'x' ? r : (r & 0x3) | 0x8;
            return v.toString(16);
        });
    }

    var Report$1 = /** @class */ (function () {
        function Report(type, collector) {
            this.url = '';
            // if (type === 'ERROR') {
            //   this.url = collector + ReportTypes.ERROR;
            // } else if (type === 'ERRORS') {
            //   this.url = collector + ReportTypes.ERRORS;
            // } else if (type === 'SEGMENT') {
            //   this.url = collector + ReportTypes.SEGMENT;
            // } else if (type === 'SEGMENTS') {
            //   this.url = collector + ReportTypes.SEGMENTS;
            // } else if (type === 'PERF') {
            //   this.url = collector + ReportTypes.PERF;
            // }
            this.type = type;
            this.url = collector;
        }
        Report.prototype.sendByFetch = function (data) {
            delete data.collector;
            if (!this.url) {
                return;
            }
            var sendRequest = new Request(this.url, { method: 'POST', body: JSON.stringify(data) });
            fetch(sendRequest)
                .then(function (response) {
                if (response.status >= 400 || response.status === 0) {
                    throw new Error('Something went wrong on api server!');
                }
            })
                .catch(function (error) {
                console.error(error);
            });
        };
        Report.prototype.sendByXhr = function (data) {
            var _this = this;
            delete data.collector;
            if (!this.url) {
                return;
            }
            var XMLHttpRequest = window.__oXMLHttpRequest_ || window.XMLHttpRequest;
            var xhr = new XMLHttpRequest();
            xhr.open('post', this.url, true);
            xhr.setRequestHeader('Content-Type', 'application/json');
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4 && xhr.status >= 200 && xhr.status < 400) {
                    if (_this.type === 'SEGMENTS')
                        resetGlobalSkySegments();
                    else if (_this.type === 'CUSTOM')
                        resetGlobalCustomMsg();
                    // console.log('Report successfully');
                }
            };
            var sendData = Array.isArray(data) ? data : [data];
            xhr.send(JSON.stringify(getHandledData(this.url, sendData)));
        };
        return Report;
    }());

    /**
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    var ErrorsCategory;
    (function (ErrorsCategory) {
        ErrorsCategory["AJAX_ERROR"] = "ajax";
        ErrorsCategory["RESOURCE_ERROR"] = "resource";
        ErrorsCategory["VUE_ERROR"] = "vue";
        ErrorsCategory["PROMISE_ERROR"] = "promise";
        ErrorsCategory["JS_ERROR"] = "js";
        ErrorsCategory["UNKNOWN_ERROR"] = "unknown";
    })(ErrorsCategory || (ErrorsCategory = {}));
    var GradeTypeEnum;
    (function (GradeTypeEnum) {
        GradeTypeEnum["INFO"] = "Info";
        GradeTypeEnum["WARNING"] = "Warning";
        GradeTypeEnum["ERROR"] = "Error";
    })(GradeTypeEnum || (GradeTypeEnum = {}));
    var ReportTypes;
    (function (ReportTypes) {
        ReportTypes["ERROR"] = "/browser/errorLog";
        ReportTypes["ERRORS"] = "/browser/errorLogs";
        ReportTypes["PERF"] = "/browser/perfData";
        ReportTypes["SEGMENT"] = "/v3/segment";
        ReportTypes["SEGMENTS"] = "/v3/segments";
    })(ReportTypes || (ReportTypes = {}));
    var SpanLayer = 'Http';
    var SpanType = 'Exit';
    var ReadyStatus;
    (function (ReadyStatus) {
        ReadyStatus[ReadyStatus["OPENED"] = 1] = "OPENED";
        ReadyStatus[ReadyStatus["DONE"] = 4] = "DONE";
    })(ReadyStatus || (ReadyStatus = {}));
    var ComponentId = 10001; // ajax
    var ServiceTag = '<browser>';

    // import windowFetch from '../interceptors/fetch';
    function traceSegment() {
        var segCollector = [];
        // inject interceptor
        xhrInterceptor();
        // windowFetch();
        window.addEventListener('xhrReadyStateChange', function (event) {
            var segment = {
                traceId: '',
                service: Config.service + ServiceTag,
                spans: [],
                serviceInstance: Config.serviceVersion,
                traceSegmentId: '',
            };
            var xhrState = event.detail.readyState;
            var openConfig = event.detail.Config.getOpenParams;
            var sendConfig = event.detail.Config.getSendParams;
            var header = event.detail.Config.getHeader;
            var url = {};
            if (openConfig[1].includes('http://') || openConfig[1].includes('https://')) {
                url = new URL(openConfig[1]);
            }
            else {
                url = openConfig[1];
            }
            // The values of xhrState are from https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState
            if (xhrState === ReadyStatus.OPENED) {
                var traceId = uuid();
                var traceSegmentId = uuid();
                segCollector.push({
                    event: event.detail,
                    startTime: new Date().getTime(),
                    traceId: traceId,
                    traceSegmentId: traceSegmentId,
                });
                var traceIdStr = String(encode(traceId));
                var segmentId = String(encode(traceSegmentId));
                var service = String(encode(segment.service));
                var instance = String(encode(segment.serviceInstance));
                var endpoint = String(encode(getPage()));
                var peer = String(encode(url.host));
                var index = segment.spans.length;
                var values = 1 + "-" + traceIdStr + "-" + segmentId + "-" + index + "-" + service + "-" + instance + "-" + endpoint + "-" + peer;
                event.detail.setRequestHeader('sw8', values);
            }
            if (xhrState === ReadyStatus.DONE) {
                // const endTime = new Date().getTime();
                for (var i = 0; i < segCollector.length; i++) {
                    if (segCollector[i].event.readyState === ReadyStatus.DONE) {
                        var url_1 = {};
                        if (segCollector[i].event.status) {
                            url_1 = new URL(segCollector[i].event.responseURL);
                        }
                        var exitSpan = {
                            operationName: getPage(),
                            startTime: segCollector[i].startTime,
                            endTime: new Date().getTime(),
                            spanId: segment.spans.length,
                            spanLayer: SpanLayer,
                            spanType: SpanType,
                            isError: event.detail.status === 0 || event.detail.status >= 400 ? true : false,
                            parentSpanId: segment.spans.length - 1,
                            componentId: ComponentId,
                            peer: url_1.host,
                            tags: Config.detailMode
                                ? [
                                    {
                                        key: 'http.method',
                                        value: openConfig[0],
                                    },
                                    {
                                        key: 'url',
                                        value: segCollector[i].event.responseURL,
                                    },
                                    GlobalVal.contextId && {
                                        key: 'contextId',
                                        value: GlobalVal.contextId,
                                    },
                                ].filter(Boolean)
                                : undefined,
                        };
                        segment = __assign(__assign({}, segment), { traceId: segCollector[i].traceId, traceSegmentId: segCollector[i].traceSegmentId });
                        var msg = __assign(__assign({}, getCommonMsg()), { traceId: segCollector[i].traceId, traceSegmentId: segCollector[i].traceSegmentId, t: 'api', uploadType: 'api', begin: segCollector[i].startTime, url: openConfig[1], time: new Date().getTime() - segCollector[i].startTime, success: event.detail.status === 0 || event.detail.status >= 400 ? true : false, requestHeader: JSON.stringify(header), requestBody: sendConfig[0], requestMethod: header.method || 'get', responseHeader: JSON.stringify(segCollector[i].event.getAllResponseHeaders()), responseStatus: segCollector[i].event.status, responseBody: ['', 'text', 'json'].includes(segCollector[i].event.responseType) ? segCollector[i].event.responseText : '{"hint":"Too much data not to show"}' });
                        segment.spans.push(exitSpan);
                        var handledMsg_1 = execHandler(UploadType.API, msg);
                        if (handledMsg_1)
                            addGlobalMonitorSegments(handledMsg_1); // 前端监控上报的信息
                        setTraceId({ url: openConfig[1] }, segCollector[i].traceId); // 记录 traceId
                        segCollector.splice(i, 1);
                    }
                }
                var handledMsg = execHandler(UploadType.SEGMENT, segment);
                if (handledMsg)
                    addGlobalSkySegments(handledMsg);
            }
        });
        var reportSeg = function () {
            if (GlobalVal.segments.length > 0) {
                new Report$1('SEGMENTS', Config.collector).sendByXhr(GlobalVal.segments);
            }
            if (GlobalVal.monitorSegments.length > 0) {
                report.sendByXhr(GlobalVal.monitorSegments);
                resetGlobalMonitorSegments();
                return;
            }
        };
        window.onbeforeunload = function (e) {
            reportSeg();
        };
        //report per 5min
        setInterval(reportSeg, 1000 * 30);
    }

    /*
     * @Description: 自定义统计
     * @Version: 0.0.1
     * @Author: ymt<mengtao.yan@hand-china.com>
     * @Date: 2021-02-25 16:42:05
     * @LastEditors: Please set LastEditors
     * @LastEditTime: 2021-02-26 16:29:09
     * @Copyright: Copyright (c) 2019, Hand
     */
    /**
     * 添加自定义统计数据
     */
    function addCustomMsg(msg) {
        addGlobalCustomMsg(msg);
    }
    /**
     * 上报自定义统计
     */
    function reportMsg() {
        new Report$1('CUSTOM', getConfig('customUrl')).sendByXhr(GlobalVal.customMsg);
    }
    function enableCustomMsg() {
        setTimeout(function () {
            if (GlobalVal.customMsg.length > 0)
                reportMsg();
            enableCustomMsg();
        }, getConfig('outtime'));
    }

    var Bombay = /** @class */ (function () {
        function Bombay() {
        }
        Bombay.prototype.register = function (options) {
            // 没有options,则不监听任何事件
            if (!options) {
                console.warn('请输入一个options');
                return;
            }
            setConfig(options);
            var page = Config.enableSPA && Config.hashRouter === 'hash' ? parseHash(location.hash.toLowerCase()) : location.pathname.toLowerCase();
            setPage(page);
            Config.enableSPA && this.addListenRouterChange();
            Config.autoTracePerf && this.sendPerf();
            Config.isError && this.addListenJs();
            Config.isAjax && this.addListenAjax();
            // 行为是一个页面内的操作
            // Config.isBehavior &&
            this.addListenBehavior();
            Config.isResource && this.sendResource();
            Config.isCustom && enableCustomMsg();
            // 绑定全局变量
            window.__bb = this;
            this.addListenUnload();
        };
        // 发送性能
        Bombay.prototype.sendPerf = function () {
            if (document.readyState === 'complete') {
                tracePerf.recordPerf();
            }
            else {
                window.addEventListener('load', function () {
                    tracePerf.recordPerf();
                }, false);
            }
            if (Config.enableSPA) {
                // 上报性能
                on('hashchange', function () { return tracePerf.recordPerf(); });
                on('historystatechanged', function () { return tracePerf.recordPerf(); });
            }
        };
        // 发送资源
        Bombay.prototype.sendResource = function () {
            'complete' === window.document.readyState ? resource.handleResource() : this.addListenResource();
        };
        // 监听资源
        Bombay.prototype.addListenResource = function () {
            on('load', function () {
                setTimeout(resource.handleResource, getConfig('resourceDelay'));
            });
        };
        // 监听行为
        Bombay.prototype.addListenBehavior = function () {
            // hackConsole();
            // Config.behavior.click &&
            this.addListenClick();
        };
        // 监听click
        Bombay.prototype.addListenClick = function () {
            on('click', handleClick); // 非输入框点击，会过滤掉点击输入框
            // on('blur', handleBlur); // 输入框失焦
        };
        // 监听路由 上报pv
        Bombay.prototype.addListenRouterChange = function () {
            hackState('pushState');
            hackState('replaceState');
            // 上报pv
            on('hashchange', handleHashchange);
            on('historystatechanged', handleHistorystatechange);
        };
        // 监听错误
        Bombay.prototype.addListenJs = function () {
            // js错误或静态资源加载错误
            on('error', function (e) { return jsError.handleErr(e); });
            //promise错误
            on('unhandledrejection', function (e) { return jsError.handleErr(e); });
        };
        Bombay.prototype.addHandler = function (type, handler) {
            var _a, _b;
            (_b = (_a = Config.handlers[type]) === null || _a === void 0 ? void 0 : _a.push) === null || _b === void 0 ? void 0 : _b.call(_a, handler);
        };
        // 监听请求
        Bombay.prototype.addListenAjax = function () {
            // windowFetch();
            // xhrInterceptor();
            traceSegment();
        };
        // beforeunload
        Bombay.prototype.addListenUnload = function () {
            this.destroy();
        };
        // 开启自定义启停trace
        Bombay.prototype.startTrace = function () {
            setGlobalContextId(randomString());
            console.log('自定义trace开启');
        };
        Bombay.prototype.stopTrace = function () {
            console.log("\u81EA\u5B9A\u4E49trace\u505C\u6B62\uFF1A\u53EF\u901A\u8FC7\u8BE5\u4E0A\u4E0B\u6587\u6807\u8BC6\u5728\u670D\u52A1\u94FE\u8DEF\u529F\u80FD\u4E2D\u8FDB\u884C\u94FE\u8DEF\u67E5\u8BE2\uFF0C\u6807\u8BC6\uFF1A" + GlobalVal.contextId);
            setGlobalContextId();
        };
        // // 移除路由
        // removeListenRouterChange() {
        //   off('hashchange', handleHashchange)
        //   off('historystatechanged', handleHistorystatechange)
        // }
        // removeListenJs() {
        //   off('error', handleErr)
        //   off('unhandledrejection', handleErr)
        // }
        // removeListenUnload() {
        //   off('load', handleResource);
        // }
        Bombay.prototype.api = function (api, success, time, code, msg) {
            report.handleCustomApi(api, success, time, code, msg, Date.now());
        };
        /**
         * 添加自定义统计数据
         */
        Bombay.prototype.addCustomMsg = function (msg) {
            addCustomMsg(msg);
        };
        Bombay.prototype.setPerformance = function (configs) {
            // history router
            setConfig(configs);
            this.sendPerf();
        };
        Bombay.prototype.destroy = function () {
            // Config.enableSPA && this.removeListenRouterChange();
            // Config.isError && this.removeListenJs()
        };
        return Bombay;
    }());
    var ClientMonitor = new Bombay();

    var global =
      (typeof globalThis !== 'undefined' && globalThis) ||
      (typeof self !== 'undefined' && self) ||
      (typeof global !== 'undefined' && global);

    var support = {
      searchParams: 'URLSearchParams' in global,
      iterable: 'Symbol' in global && 'iterator' in Symbol,
      blob:
        'FileReader' in global &&
        'Blob' in global &&
        (function() {
          try {
            new Blob();
            return true
          } catch (e) {
            return false
          }
        })(),
      formData: 'FormData' in global,
      arrayBuffer: 'ArrayBuffer' in global
    };

    function isDataView(obj) {
      return obj && DataView.prototype.isPrototypeOf(obj)
    }

    if (support.arrayBuffer) {
      var viewClasses = [
        '[object Int8Array]',
        '[object Uint8Array]',
        '[object Uint8ClampedArray]',
        '[object Int16Array]',
        '[object Uint16Array]',
        '[object Int32Array]',
        '[object Uint32Array]',
        '[object Float32Array]',
        '[object Float64Array]'
      ];

      var isArrayBufferView =
        ArrayBuffer.isView ||
        function(obj) {
          return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
        };
    }

    function normalizeName(name) {
      if (typeof name !== 'string') {
        name = String(name);
      }
      if (/[^a-z0-9\-#$%&'*+.^_`|~!]/i.test(name) || name === '') {
        throw new TypeError('Invalid character in header field name')
      }
      return name.toLowerCase()
    }

    function normalizeValue(value) {
      if (typeof value !== 'string') {
        value = String(value);
      }
      return value
    }

    // Build a destructive iterator for the value list
    function iteratorFor(items) {
      var iterator = {
        next: function() {
          var value = items.shift();
          return {done: value === undefined, value: value}
        }
      };

      if (support.iterable) {
        iterator[Symbol.iterator] = function() {
          return iterator
        };
      }

      return iterator
    }

    function Headers(headers) {
      this.map = {};

      if (headers instanceof Headers) {
        headers.forEach(function(value, name) {
          this.append(name, value);
        }, this);
      } else if (Array.isArray(headers)) {
        headers.forEach(function(header) {
          this.append(header[0], header[1]);
        }, this);
      } else if (headers) {
        Object.getOwnPropertyNames(headers).forEach(function(name) {
          this.append(name, headers[name]);
        }, this);
      }
    }

    Headers.prototype.append = function(name, value) {
      name = normalizeName(name);
      value = normalizeValue(value);
      var oldValue = this.map[name];
      this.map[name] = oldValue ? oldValue + ', ' + value : value;
    };

    Headers.prototype['delete'] = function(name) {
      delete this.map[normalizeName(name)];
    };

    Headers.prototype.get = function(name) {
      name = normalizeName(name);
      return this.has(name) ? this.map[name] : null
    };

    Headers.prototype.has = function(name) {
      return this.map.hasOwnProperty(normalizeName(name))
    };

    Headers.prototype.set = function(name, value) {
      this.map[normalizeName(name)] = normalizeValue(value);
    };

    Headers.prototype.forEach = function(callback, thisArg) {
      for (var name in this.map) {
        if (this.map.hasOwnProperty(name)) {
          callback.call(thisArg, this.map[name], name, this);
        }
      }
    };

    Headers.prototype.keys = function() {
      var items = [];
      this.forEach(function(value, name) {
        items.push(name);
      });
      return iteratorFor(items)
    };

    Headers.prototype.values = function() {
      var items = [];
      this.forEach(function(value) {
        items.push(value);
      });
      return iteratorFor(items)
    };

    Headers.prototype.entries = function() {
      var items = [];
      this.forEach(function(value, name) {
        items.push([name, value]);
      });
      return iteratorFor(items)
    };

    if (support.iterable) {
      Headers.prototype[Symbol.iterator] = Headers.prototype.entries;
    }

    function consumed(body) {
      if (body.bodyUsed) {
        return Promise.reject(new TypeError('Already read'))
      }
      body.bodyUsed = true;
    }

    function fileReaderReady(reader) {
      return new Promise(function(resolve, reject) {
        reader.onload = function() {
          resolve(reader.result);
        };
        reader.onerror = function() {
          reject(reader.error);
        };
      })
    }

    function readBlobAsArrayBuffer(blob) {
      var reader = new FileReader();
      var promise = fileReaderReady(reader);
      reader.readAsArrayBuffer(blob);
      return promise
    }

    function readBlobAsText(blob) {
      var reader = new FileReader();
      var promise = fileReaderReady(reader);
      reader.readAsText(blob);
      return promise
    }

    function readArrayBufferAsText(buf) {
      var view = new Uint8Array(buf);
      var chars = new Array(view.length);

      for (var i = 0; i < view.length; i++) {
        chars[i] = String.fromCharCode(view[i]);
      }
      return chars.join('')
    }

    function bufferClone(buf) {
      if (buf.slice) {
        return buf.slice(0)
      } else {
        var view = new Uint8Array(buf.byteLength);
        view.set(new Uint8Array(buf));
        return view.buffer
      }
    }

    function Body() {
      this.bodyUsed = false;

      this._initBody = function(body) {
        /*
          fetch-mock wraps the Response object in an ES6 Proxy to
          provide useful test harness features such as flush. However, on
          ES5 browsers without fetch or Proxy support pollyfills must be used;
          the proxy-pollyfill is unable to proxy an attribute unless it exists
          on the object before the Proxy is created. This change ensures
          Response.bodyUsed exists on the instance, while maintaining the
          semantic of setting Request.bodyUsed in the constructor before
          _initBody is called.
        */
        this.bodyUsed = this.bodyUsed;
        this._bodyInit = body;
        if (!body) {
          this._bodyText = '';
        } else if (typeof body === 'string') {
          this._bodyText = body;
        } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
          this._bodyBlob = body;
        } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
          this._bodyFormData = body;
        } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
          this._bodyText = body.toString();
        } else if (support.arrayBuffer && support.blob && isDataView(body)) {
          this._bodyArrayBuffer = bufferClone(body.buffer);
          // IE 10-11 can't handle a DataView body.
          this._bodyInit = new Blob([this._bodyArrayBuffer]);
        } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
          this._bodyArrayBuffer = bufferClone(body);
        } else {
          this._bodyText = body = Object.prototype.toString.call(body);
        }

        if (!this.headers.get('content-type')) {
          if (typeof body === 'string') {
            this.headers.set('content-type', 'text/plain;charset=UTF-8');
          } else if (this._bodyBlob && this._bodyBlob.type) {
            this.headers.set('content-type', this._bodyBlob.type);
          } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
            this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
          }
        }
      };

      if (support.blob) {
        this.blob = function() {
          var rejected = consumed(this);
          if (rejected) {
            return rejected
          }

          if (this._bodyBlob) {
            return Promise.resolve(this._bodyBlob)
          } else if (this._bodyArrayBuffer) {
            return Promise.resolve(new Blob([this._bodyArrayBuffer]))
          } else if (this._bodyFormData) {
            throw new Error('could not read FormData body as blob')
          } else {
            return Promise.resolve(new Blob([this._bodyText]))
          }
        };

        this.arrayBuffer = function() {
          if (this._bodyArrayBuffer) {
            var isConsumed = consumed(this);
            if (isConsumed) {
              return isConsumed
            }
            if (ArrayBuffer.isView(this._bodyArrayBuffer)) {
              return Promise.resolve(
                this._bodyArrayBuffer.buffer.slice(
                  this._bodyArrayBuffer.byteOffset,
                  this._bodyArrayBuffer.byteOffset + this._bodyArrayBuffer.byteLength
                )
              )
            } else {
              return Promise.resolve(this._bodyArrayBuffer)
            }
          } else {
            return this.blob().then(readBlobAsArrayBuffer)
          }
        };
      }

      this.text = function() {
        var rejected = consumed(this);
        if (rejected) {
          return rejected
        }

        if (this._bodyBlob) {
          return readBlobAsText(this._bodyBlob)
        } else if (this._bodyArrayBuffer) {
          return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))
        } else if (this._bodyFormData) {
          throw new Error('could not read FormData body as text')
        } else {
          return Promise.resolve(this._bodyText)
        }
      };

      if (support.formData) {
        this.formData = function() {
          return this.text().then(decode)
        };
      }

      this.json = function() {
        return this.text().then(JSON.parse)
      };

      return this
    }

    // HTTP methods whose capitalization should be normalized
    var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'];

    function normalizeMethod(method) {
      var upcased = method.toUpperCase();
      return methods.indexOf(upcased) > -1 ? upcased : method
    }

    function Request$1(input, options) {
      if (!(this instanceof Request$1)) {
        throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.')
      }

      options = options || {};
      var body = options.body;

      if (input instanceof Request$1) {
        if (input.bodyUsed) {
          throw new TypeError('Already read')
        }
        this.url = input.url;
        this.credentials = input.credentials;
        if (!options.headers) {
          this.headers = new Headers(input.headers);
        }
        this.method = input.method;
        this.mode = input.mode;
        this.signal = input.signal;
        if (!body && input._bodyInit != null) {
          body = input._bodyInit;
          input.bodyUsed = true;
        }
      } else {
        this.url = String(input);
      }

      this.credentials = options.credentials || this.credentials || 'same-origin';
      if (options.headers || !this.headers) {
        this.headers = new Headers(options.headers);
      }
      this.method = normalizeMethod(options.method || this.method || 'GET');
      this.mode = options.mode || this.mode || null;
      this.signal = options.signal || this.signal;
      this.referrer = null;

      if ((this.method === 'GET' || this.method === 'HEAD') && body) {
        throw new TypeError('Body not allowed for GET or HEAD requests')
      }
      this._initBody(body);

      if (this.method === 'GET' || this.method === 'HEAD') {
        if (options.cache === 'no-store' || options.cache === 'no-cache') {
          // Search for a '_' parameter in the query string
          var reParamSearch = /([?&])_=[^&]*/;
          if (reParamSearch.test(this.url)) {
            // If it already exists then set the value with the current time
            this.url = this.url.replace(reParamSearch, '$1_=' + new Date().getTime());
          } else {
            // Otherwise add a new '_' parameter to the end with the current time
            var reQueryString = /\?/;
            this.url += (reQueryString.test(this.url) ? '&' : '?') + '_=' + new Date().getTime();
          }
        }
      }
    }

    Request$1.prototype.clone = function() {
      return new Request$1(this, {body: this._bodyInit})
    };

    function decode(body) {
      var form = new FormData();
      body
        .trim()
        .split('&')
        .forEach(function(bytes) {
          if (bytes) {
            var split = bytes.split('=');
            var name = split.shift().replace(/\+/g, ' ');
            var value = split.join('=').replace(/\+/g, ' ');
            form.append(decodeURIComponent(name), decodeURIComponent(value));
          }
        });
      return form
    }

    function parseHeaders(rawHeaders) {
      var headers = new Headers();
      // Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space
      // https://tools.ietf.org/html/rfc7230#section-3.2
      var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ');
      // Avoiding split via regex to work around a common IE11 bug with the core-js 3.6.0 regex polyfill
      // https://github.com/github/fetch/issues/748
      // https://github.com/zloirock/core-js/issues/751
      preProcessedHeaders
        .split('\r')
        .map(function(header) {
          return header.indexOf('\n') === 0 ? header.substr(1, header.length) : header
        })
        .forEach(function(line) {
          var parts = line.split(':');
          var key = parts.shift().trim();
          if (key) {
            var value = parts.join(':').trim();
            headers.append(key, value);
          }
        });
      return headers
    }

    Body.call(Request$1.prototype);

    function Response(bodyInit, options) {
      if (!(this instanceof Response)) {
        throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.')
      }
      if (!options) {
        options = {};
      }

      this.type = 'default';
      this.status = options.status === undefined ? 200 : options.status;
      this.ok = this.status >= 200 && this.status < 300;
      this.statusText = 'statusText' in options ? options.statusText : '';
      this.headers = new Headers(options.headers);
      this.url = options.url || '';
      this._initBody(bodyInit);
    }

    Body.call(Response.prototype);

    Response.prototype.clone = function() {
      return new Response(this._bodyInit, {
        status: this.status,
        statusText: this.statusText,
        headers: new Headers(this.headers),
        url: this.url
      })
    };

    Response.error = function() {
      var response = new Response(null, {status: 0, statusText: ''});
      response.type = 'error';
      return response
    };

    var redirectStatuses = [301, 302, 303, 307, 308];

    Response.redirect = function(url, status) {
      if (redirectStatuses.indexOf(status) === -1) {
        throw new RangeError('Invalid status code')
      }

      return new Response(null, {status: status, headers: {location: url}})
    };

    var DOMException = global.DOMException;
    try {
      new DOMException();
    } catch (err) {
      DOMException = function(message, name) {
        this.message = message;
        this.name = name;
        var error = Error(message);
        this.stack = error.stack;
      };
      DOMException.prototype = Object.create(Error.prototype);
      DOMException.prototype.constructor = DOMException;
    }

    function fetch$1(input, init) {
      return new Promise(function(resolve, reject) {
        var request = new Request$1(input, init);

        if (request.signal && request.signal.aborted) {
          return reject(new DOMException('Aborted', 'AbortError'))
        }

        var xhr = new XMLHttpRequest();

        function abortXhr() {
          xhr.abort();
        }

        xhr.onload = function() {
          var options = {
            status: xhr.status,
            statusText: xhr.statusText,
            headers: parseHeaders(xhr.getAllResponseHeaders() || '')
          };
          options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL');
          var body = 'response' in xhr ? xhr.response : xhr.responseText;
          setTimeout(function() {
            resolve(new Response(body, options));
          }, 0);
        };

        xhr.onerror = function() {
          setTimeout(function() {
            reject(new TypeError('Network request failed'));
          }, 0);
        };

        xhr.ontimeout = function() {
          setTimeout(function() {
            reject(new TypeError('Network request failed'));
          }, 0);
        };

        xhr.onabort = function() {
          setTimeout(function() {
            reject(new DOMException('Aborted', 'AbortError'));
          }, 0);
        };

        function fixUrl(url) {
          try {
            return url === '' && global.location.href ? global.location.href : url
          } catch (e) {
            return url
          }
        }

        xhr.open(request.method, fixUrl(request.url), true);

        if (request.credentials === 'include') {
          xhr.withCredentials = true;
        } else if (request.credentials === 'omit') {
          xhr.withCredentials = false;
        }

        if ('responseType' in xhr) {
          if (support.blob) {
            xhr.responseType = 'blob';
          } else if (
            support.arrayBuffer &&
            request.headers.get('Content-Type') &&
            request.headers.get('Content-Type').indexOf('application/octet-stream') !== -1
          ) {
            xhr.responseType = 'arraybuffer';
          }
        }

        if (init && typeof init.headers === 'object' && !(init.headers instanceof Headers)) {
          Object.getOwnPropertyNames(init.headers).forEach(function(name) {
            xhr.setRequestHeader(name, normalizeValue(init.headers[name]));
          });
        } else {
          request.headers.forEach(function(value, name) {
            xhr.setRequestHeader(name, value);
          });
        }

        if (request.signal) {
          request.signal.addEventListener('abort', abortXhr);

          xhr.onreadystatechange = function() {
            // DONE (success or failure)
            if (xhr.readyState === 4) {
              request.signal.removeEventListener('abort', abortXhr);
            }
          };
        }

        xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit);
      })
    }

    fetch$1.polyfill = true;

    if (!global.fetch) {
      global.fetch = fetch$1;
      global.Headers = Headers;
      global.Request = Request$1;
      global.Response = Response;
    }

    /**
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    function windowFetch() {
      window.fetch = fetch$1;
    } // 旧的重写 fetch

    /**
     * 提前执行 windowFetch， 使用 xhr 重写 fetch
     * 防止出现 register 时间过晚，fetch 请求无法拦截的问题
     */
    windowFetch();
    window.ClientMonitor = ClientMonitor;

    return ClientMonitor;

})));
